﻿package we3d.mesh 
{
	import we3d.material.Surface;
	import we3d.mesh.Vertex;
	import we3d.mesh.UVCoord;
	import we3d.scene.SceneObject;
	import flash.geom.Matrix;

	/**
	* Faces are the polygons of a scene object
	* 
	* <code><pre>
	* 	import we3d.scene.SceneObject;
	* 
	* 	var so:SceneObject = new SceneObject();
	* 
	* 	so.addPoint(0,0,0);
	* 	so.addPoint(100,0,0);
	* 	so.addPoint(100,100,0);
	* 	so.addPoint(100,100,100);
	* 	so.addPoint(0, 100,100);
	* 
	* 	var f1:Face = so.addPolygon(surface, 0,1,2);		// add a Triangle
	* 	var f2:Face = so.addPolygon(surface, 0,1,2,3,4);	// add a Polygon
	* 
	* </pre></code>
	*/
	public class Face 
	{
		public function Face () {}
		
		/** 
		* The material of the face 
		*/
		public var surface:Surface;
		/** 
		* Avarage center of the polygon
		*/
		public var ax:Number;		public var ay:Number;		public var az:Number;
		/**
		* The normal of the face
		*/
		public var normal:Vertex=new Vertex();
		/**
		* The sortFar is added to the depth value for polygon sorting
		*/
		public var sortFar:Number=0;
		/**
		* @private
		* References to the first 3 Points in the Polygon
		*/
		public var a:Vertex;
		/**
		* @private
		*/
		public var b:Vertex;
		/**
		* @private
		*/
		public var c:Vertex;
		/**
		* @private
		* References to the points
		*/
		public var vtxs:Array;
		/**
		* UV Coords (max len 3)
		*/
		public var uvs:Array;
		/**
		* @private
		* Precalculated Matrix for native textures
		*/
		public var tMat:Matrix;
		/**
		* @private
		* depth value in camera space
		*/
		public var z:Number;
		/**
		* Vertice count, have to be the same length like the vertices
		*/
		public var vLen:int;
		public var so:SceneObject;
		public var u1:Number;		public var u2:Number;		public var u3:Number;
		public var v1:Number;		public var v2:Number;		public var v3:Number;
		
		public function init (obj:SceneObject) :void {
			
			so = obj;
			
			if(vtxs != null) {
				
				var L:int = vtxs.length;
				vLen = L;
				
				if(L > 0) {
					
					a = vtxs[0];
					
					if(L > 1) {
						
						b = vtxs[1];
						ax = ay = az = 0;
						
						var p:Vertex;
						var i:int;
						
						for(i=0; i<L; i++) {
							p = vtxs[i];
							ax += p.x;
							ay += p.y;
							az += p.z;
						}
						
						ax /= L;
						ay /= L;
						az /= L;
						
						if(L > 2) {
							
							c = vtxs[2];
							
							var x1:Number = b.x-a.x;	
							var y1:Number = b.y-a.y;	
							var z1:Number = b.z-a.z;
							
							var x2:Number = c.x-a.x;		
							var y2:Number = c.y-a.y;		
							var z2:Number = c.z-a.z;
							
							normal.x = y1 * z2 - z1 * y2;
							normal.y = z1 * x2 - x1 * z2;
							normal.z = x1 * y2 - y1 * x2;
							
							x1 = Math.sqrt(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z);
							normal.x /= x1;		
							normal.y /= x1;		
							normal.z /= x1;
						}
					}
				}
			}
		}
		
		public function addUvCoord (u:Number=0, v:Number=0) :int {
			if(uvs == null) uvs = [];
			var L:int = uvs.push(new UVCoord(u, v));
			if(L==3) surface.initFace(this);
			return L-1;
		}
	}
}
